"""
Data fetching node - retrieves data for analysis.
"""
from typing import Dict, Any
import pandas as pd
from ..tools.data_loader import DataLoader


def fetch_data(state: Dict[str, Any]) -> Dict[str, Any]:
    """
    Fetch data for the specified time range and metric.

    Args:
        state: Current state dict

    Returns:
        Updated state dict with data loaded
    """
    # In a real implementation, this would connect to a database or data warehouse
    # For now, we'll use the data if it's already in state
    if state.get('data') is not None:
        data = state['data']
    else:
        # If no data provided, create empty DataFrame
        # In production, this would query from your data source
        data = pd.DataFrame()
        state['error'] = "No data provided. Please load data before running analysis."
        state['next_action'] = 'end'
        return state

    # Initialize data loader
    loader = DataLoader()

    # Auto-detect dimensions and metrics from data
    if 'dimensions' not in state or not state['dimensions']:
        # Identify dimension columns (typically string/categorical columns)
        dimension_candidates = []
        for col in data.columns:
            if col not in ['date', 'datetime', 'timestamp']:
                if data[col].dtype == 'object' or data[col].dtype.name == 'category':
                    dimension_candidates.append(col)

        state['dimensions'] = dimension_candidates

    # Identify metric columns (numerical columns)
    metric_candidates = []
    for col in data.columns:
        if col not in state.get('dimensions', []) and col not in ['date', 'datetime', 'timestamp']:
            if pd.api.types.is_numeric_dtype(data[col]):
                metric_candidates.append(col)

    # Store metadata
    state['metric_metadata'] = {
        'available_metrics': metric_candidates,
        'available_dimensions': state.get('dimensions', []),
        'total_rows': len(data),
        'date_range': (data['date'].min(), data['date'].max()) if 'date' in data.columns else None
    }

    # Filter data by time range
    time_column = 'date'  # Assuming 'date' column exists
    if time_column in data.columns:
        time_range = state.get('time_range')
        if time_range:
            data_compared= loader.filter_by_time_range(
                data,
                time_column,
                time_range[0],
                time_range[1]
            )
        baseline_period = state.get('baseline_period')
        if baseline_period:
            data_baseline = loader.filter_by_time_range(
                data,
                time_column,
                baseline_period[0],
                baseline_period[1]
            )
    
    # merge compared and baseline data
    if 'data_compared' in locals() and 'data_baseline' in locals():
        data = pd.concat([data_compared, data_baseline]).reset_index(drop=True)
    else:
        if 'data_compared' in locals():
            data = data_compared
        if 'data_baseline' in locals():
            data = data_baseline

    state['data'] = data
    state['next_action'] = 'detect_anomalies'

    return state
